﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Minestorm.Retro.GameLogic;

namespace Minestorm.Retro.Entities
{
    public class Fireball : Entity
    {
        private Vector2 _lastPosition;

        public Fireball(GraphicsDevice graphics, Vector2 position, Vector2 shipPosition)
            : base(graphics, position)
        {
            Speed = 0.25f;

            Angle = (float)Math.Atan2(position.Y - shipPosition.Y, position.X - shipPosition.X) - MathHelper.ToRadians(-90);

            _lastPosition = position;

            Points = 110;
        }

        public float Angle { get; set; }

        public float Speed { get; set; }

		public Vector2 LastPosition { get { return _lastPosition; } }

        public override void  Initialize()
        {
            var verticies = new VertexPositionColor[9];
            verticies[0] = new VertexPositionColor(new Vector3(0, 0, 0), Constants.VectorColor);
            verticies[1] = new VertexPositionColor(new Vector3(-.3f, 0, 0), Constants.VectorColor);
            verticies[2] = new VertexPositionColor(new Vector3(-.2f, .2f, 0), Constants.VectorColor);
            verticies[3] = new VertexPositionColor(new Vector3(0, .3f, 0), Constants.VectorColor);
            verticies[4] = new VertexPositionColor(new Vector3(.2f, .2f, 0), Constants.VectorColor);
            verticies[5] = new VertexPositionColor(new Vector3(.3f, 0, 0), Constants.VectorColor);
            verticies[6] = new VertexPositionColor(new Vector3(.2f, -.2f, 0), Constants.VectorColor);
            verticies[7] = new VertexPositionColor(new Vector3(0, -.3f, 0), Constants.VectorColor);
            verticies[8] = new VertexPositionColor(new Vector3(-.2f, -.2f, 0), Constants.VectorColor);

            SetVerticies(verticies);

            SetIndicies(
                new NamedShortArray("fireball", true, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8)
                );
        }

        protected float Radius
        {
            get { return .3f; }
        }

        public bool CheckPointCollision(Vector3[] points)
        {
            foreach (var point in points)
            {
                var hit = Math.Sqrt(point.X - Position.X) + Math.Sqrt(point.Y - Position.Y) < Math.Sqrt(Radius);

                if (hit)
                    return true;
            }

            return false;
        }

		public Boolean CheckLineCollision(Vector2 ls, Vector2 le, Vector3[] verts)
		{
			Vector2[] verts2 = new Vector2[verts.Length];
			for (int i = 0; i < verts.Length; i++)
				verts2[i] = new Vector2(verts[i].X, verts[i].Y);
			return CheckLineCollision(ls, le, verts2);
		}
		public Boolean CheckLineCollision(Vector2 ls, Vector2 le, Vector2[] verts)
		{
			Vector2 v1, v2;
			var vertCount = verts.Count();
			for (var i = 0; i < vertCount; i++)
			{
				v1 = verts[i];
				v2 = verts[(i + 1) % vertCount];

				if (CheckLineIntersection(ls, le, v1, v2))
					return true;
			}

			return false;
		}
		bool CheckLineIntersection(Vector2 a, Vector2 b, Vector2 c, Vector2 d)
		{
			float denominator = ((b.X - a.X) * (d.Y - c.Y)) - ((b.Y - a.Y) * (d.X - c.X));
			float numerator1 = ((a.Y - c.Y) * (d.X - c.X)) - ((a.X - c.X) * (d.Y - c.Y));
			float numerator2 = ((a.Y - c.Y) * (b.X - a.X)) - ((a.X - c.X) * (b.Y - a.Y));

			if (denominator == 0) return numerator1 == 0 && numerator2 == 0;

			float r = numerator1 / denominator;
			float s = numerator2 / denominator;

			return (r >= 0 && r <= 1) && (s >= 0 && s <= 1);
		}

        public override Matrix GetWorld(string indexBufferName)
        {
            return Matrix.Identity * Matrix.CreateTranslation(new Vector3(Position, 0f));
        }

        public void Move()
        {
            _lastPosition = Position;

            Position = new Vector2(Position.X + (float)Math.Sin(-Angle) * Speed, Position.Y + (float)Math.Cos(-Angle) * Speed);

            if (Position.X < -30)
                ShouldDraw = false;
            if (Position.X > 30)
                ShouldDraw = false;
            if (Position.Y < -20)
                ShouldDraw = false;
            if (Position.Y > 20)
                ShouldDraw = false;
        }
    }
}
